package org.qiyu.live.im.core.server.handler.Impl;

import com.alibaba.fastjson2.JSON;
import io.netty.channel.ChannelHandlerContext;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.qiyu.live.im.constants.AppldEnum;
import org.qiyu.live.im.constants.ImConstants;
import org.qiyu.live.im.constants.ImMsgCodeEnum;
import org.qiyu.live.im.core.server.common.ChannelHandlerContextCache;
import org.qiyu.live.im.core.server.common.ImContextAttr;
import org.qiyu.live.im.core.server.common.ImContextUtils;
import org.qiyu.live.im.core.server.common.ImMsg;
import org.qiyu.live.im.core.server.handler.SimplyHandler;
import org.qiyu.live.im.core.server.interfaces.constants.ImCoreServicerConstants;
import org.qiyu.live.im.dto.ImMsgBody;
import org.qiyu.live.im.interfaces.ImTokenRpc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @Description: 登录消息处理
 * @Author: 张广焱
 * @Date: 2023-12-03 13:14
 */
@Component
public class LoginMsgHandler implements SimplyHandler {
    private static final Logger logger = LoggerFactory.getLogger(LoginMsgHandler.class);
    @DubboReference
    private ImTokenRpc imTokenRpc;
    @Resource
    private StringRedisTemplate  stringRedisTemplate;
    @Override
    public void handler(ChannelHandlerContext ctx, ImMsg imMsg) {
        if (ImContextUtils.getUserId(ctx) != null)  return;
        byte[] body = imMsg.getBody();
        if (body == null||body.length==0) {
            ctx.close();
            logger.error("body error,imMsg is {}",imMsg);
           throw  new IllegalArgumentException("body error");
        }
        //json 转实体
        ImMsgBody imMsgBody = JSON.parseObject(new String(body), ImMsgBody.class);
        Long userIdFromMsg = imMsgBody.getUserId();
        Integer appId = imMsgBody.getAppId();
        String token = imMsgBody.getToken();
        if (StringUtils.isEmpty(token) || userIdFromMsg < 10000 || appId < 10000) {
            ctx.close();
            logger.error("param error,imMsg is {}",imMsg);
            throw  new IllegalArgumentException("param error");
        }
        Long userId = imTokenRpc.getUserIdByToken(token);
        //token校验成功,而且和传递过来的userid是同一个,则允许建立连接
        if (userId != null && userId.equals(userIdFromMsg)) {
             //按照useriD保存好相关的channel对象信息
             ChannelHandlerContextCache.put(userId,ctx);
             //将userId绑定到channel上下文中 修改ctx的属性
             ImContextUtils.setUserId(ctx,userId);
            ImContextUtils.setAppId(ctx, appId);
             ImMsgBody respBody = new ImMsgBody();
             respBody.setAppId(AppldEnum.QIYU_LIVE_BIZ.getCode());
             respBody.setUserId(userId);
             respBody.setData("true");
             ImMsg respMsg = ImMsg.build(ImMsgCodeEnum.IM_LOGIN_MSG.getCode(), JSON.toJSONString(respBody));
             //将用户信息储存起来
             stringRedisTemplate.opsForValue().set(ImCoreServicerConstants.IM_BIND_IP_KEY+appId+userId,ChannelHandlerContextCache.getServerIpAddress(),ImConstants.DEFAULT_HEART_BEAT_GAP*2, TimeUnit.SECONDS);
             logger.info("[LoginMsgHandler] login success,userId is {},appId is {}",userId,appId);
             ctx.writeAndFlush(respMsg);
            return;
         }
        ctx.close();
        logger.error("token check error,imMsg is {}",imMsg);
        throw  new IllegalArgumentException("token check error");
    }
}
